/************************************************************************
 * <br>
 * <ul>
 * <li>版权所有：唐山弘川科技有限公司 2009－2020</li>
 * <li>创建日期：2009-8-10</li>
 * <li>初始作者：刘川</li>
 * </ul>
 * <ul>
 * <b>修订历史</b>
 * <li>1、</li>
 * </ul>
 ***********************************************************************/
package com.hy.enterprise.framework.persistence.domain.query ;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import com.hy.enterprise.framework.persistence.domain.query.conditions.ConditionalExpression;
import com.hy.enterprise.framework.persistence.domain.query.internal.AliasFactory;
import com.hy.enterprise.framework.persistence.domain.query.internal.managedobjects.AliasedLibraManagedObject;
import com.hy.enterprise.framework.persistence.domain.query.internal.managedobjects.CollectionAssociationPath;
import com.hy.enterprise.framework.persistence.domain.query.internal.managedobjects.LibraManagedObject;
import com.hy.enterprise.framework.util.lang.ObjectUtil;

/**
 * <ul>
 * <li>设计作者：刘川</li>
 * <li>设计日期：2009-8-10</li>
 * <li>设计时间：下午04:56:16</li>
 * <li>设计目的：</li>
 * </ul>
 * <ul>
 * <b>修订历史</b>
 * <li>1、</li>
 * </ul>
 * 
 * @param <T>
 * @param <S>
 */
class AbstractSchemaTypeFromClause < T , S > extends FromClause < T , S >
{
	@ SuppressWarnings ( "unused" )
	private final Class < T >	abstractSchemaType ;

	/**
	 * 构造函数
	 * 
	 * @param previousClauseFragment
	 * @param abstractSchemaType
	 */
	AbstractSchemaTypeFromClause (
	                               AbstractClause previousClauseFragment ,
	                               Class < T > abstractSchemaType )
	{
		super (
		        previousClauseFragment ) ;
		this.abstractSchemaType =
		                          abstractSchemaType ;
	}
}

/**
 * <ul>
 * <li>设计作者：刘川</li>
 * <li>设计日期：2009-8-10</li>
 * <li>设计时间：下午04:56:23</li>
 * <li>设计目的：</li>
 * </ul>
 * <ul>
 * <b>修订历史</b>
 * <li>1、</li>
 * </ul>
 * 
 * @param <T>
 * @param <S>
 */
class CollectionValuedFromClause < T , S > extends FromClause < T , S >
{
	@ SuppressWarnings ( "unused" )
	private final Collection < T >	collectionValued ;

	/**
	 * 构造函数
	 * 
	 * @param previousClauseFragment
	 * @param collectionValued
	 */
	CollectionValuedFromClause (
	                             AbstractClause previousClauseFragment ,
	                             Collection < T > collectionValued )
	{
		super (
		        previousClauseFragment ) ;
		this.collectionValued =
		                        collectionValued ;
	}
}

/**
 * <ul>
 * <li>设计作者：刘川</li>
 * <li>设计日期：2009-8-10</li>
 * <li>设计时间：下午04:55:51</li>
 * <li>设计目的：</li>
 * </ul>
 * <ul>
 * <b>修订历史</b>
 * <li>1、</li>
 * </ul>
 * 
 * @param <T>
 * @param <S>
 */
class InCollectionFromClause < T , S > extends FromClause < T , S >
{
	@ SuppressWarnings ( "unused" )
	private final InCollection < T >	inCollection ;

	/**
	 * 构造函数
	 * 
	 * @param previousClauseFragment
	 * @param inCollection
	 */
	InCollectionFromClause (
	                         AbstractClause previousClauseFragment ,
	                         InCollection < T > inCollection )
	{
		super (
		        previousClauseFragment ) ;
		this.inCollection =
		                    inCollection ;
	}
}

/**
 * <ul>
 * <li>设计作者：刘川</li>
 * <li>设计日期：2009-8-10</li>
 * <li>设计时间：下午04:56:46</li>
 * <li>设计目的：</li>
 * </ul>
 * <ul>
 * <b>修订历史</b>
 * <li>1、</li>
 * </ul>
 * 
 * @param <T>
 * @param <S>
 */
class SingleValuedFromClause < T , S > extends FromClause < T , S >
{
	@ SuppressWarnings ( "unused" )
	private final T	singleValued ;

	/**
	 * 构造函数
	 * 
	 * @param previousClauseFragment
	 * @param singleValued
	 */
	SingleValuedFromClause (
	                         AbstractClause previousClauseFragment ,
	                         T singleValued )
	{
		super (
		        previousClauseFragment ) ;
		this.singleValued =
		                    singleValued ;
	}
}

/**
 * <ul>
 * <li>设计作者：刘川</li>
 * <li>设计日期：2009-8-10</li>
 * <li>设计时间：下午04:37:53</li>
 * <li>设计目的：</li>
 * </ul>
 * <ul>
 * <b>修订历史</b>
 * <li>1、</li>
 * </ul>
 * 
 * @param <T>
 * @param <S>
 */
public class FromClause < T , S > extends AbstractClause implements
        ISubQuery < S >
{
	/**
	 * <ul>
	 * <li>设计作者：刘川</li>
	 * <li>设计日期：2009-8-10</li>
	 * <li>设计时间：下午04:47:21</li>
	 * <li>设计目的：</li>
	 * </ul>
	 * <ul>
	 * <b>修订历史</b>
	 * <li>1、</li>
	 * </ul>
	 */
	private static enum JoinType
	{
		INNER (
		       " INNER JOIN " ) ,
		LEFT (
		      " LEFT OUTER JOIN " ) ;
		final String	stringForm ;

		/**
		 * 构造函数
		 * 
		 * @param stringForm
		 */
		private JoinType (
		                   String stringForm )
		{
			this.stringForm =
			                  stringForm ;
		}
	}

	/**
	 * <ul>
	 * <li>设计作者：刘川</li>
	 * <li>设计日期：2009-8-10</li>
	 * <li>设计时间：下午04:38:04</li>
	 * <li>设计目的：</li>
	 * </ul>
	 * <ul>
	 * <b>修订历史</b>
	 * <li>1、</li>
	 * </ul>
	 * 
	 * @param <J>
	 */
	public class JoinClause < J >
	{
		private final boolean	fetch ;

		private final JoinType	joinType ;

		protected J		       joinIdentificationVariable ;

		/**
		 * 构造函数
		 * 
		 * @param joinIdentificationVariable
		 * @param joinType
		 * @param fetch
		 */
		private JoinClause (
		                     J joinIdentificationVariable ,
		                     JoinType joinType ,
		                     boolean fetch )
		{
			this.joinIdentificationVariable =
			                                  joinIdentificationVariable ;
			this.joinType =
			                joinType ;
			this.fetch =
			             fetch ;
		}

		/**
		 * <ul>
		 * <li>设计作者：刘川</li>
		 * <li>设计日期：2009-8-10</li>
		 * <li>设计时间：下午04:38:54</li>
		 * <li>设计目的：</li>
		 * </ul>
		 * <ul>
		 * <b>修订历史</b>
		 * <li>1、</li>
		 * </ul>
		 * 
		 * @param groupByItem
		 * @param more
		 * @return
		 */
		public GroupByClause < S > groupBy (
		                                     Object groupByItem ,
		                                     Object ... more )
		{
			return new GroupByClause < S > (
			                                 FromClause.this ,
			                                 ObjectUtil
			                                           .merge (
			                                                    Object.class ,
			                                                    groupByItem ,
			                                                    more ) ) ;
		}

		/**
		 * <ul>
		 * <li>设计作者：刘川</li>
		 * <li>设计日期：2009-8-10</li>
		 * <li>设计时间：下午04:38:20</li>
		 * <li>设计目的：</li>
		 * </ul>
		 * <ul>
		 * <b>修订历史</b>
		 * <li>1、</li>
		 * </ul>
		 * 
		 * @param <K>
		 * @param joinIdentificationVariable
		 * @return
		 */
		public < K > NotFetchingJoinClause < K > innerJoin (
		                                                     Collection < K > joinIdentificationVariable )
		{
			NotFetchingJoinClause < K > joinClause =
			                                         new NotFetchingJoinClause < K > (
			                                                                           null ,
			                                                                           FromClause.JoinType.INNER ) ;
			FromClause.this.joins
			                     .add ( joinClause ) ;
			return joinClause ;
		}

		/**
		 * <ul>
		 * <li>设计作者：刘川</li>
		 * <li>设计日期：2009-8-10</li>
		 * <li>设计时间：下午04:38:15</li>
		 * <li>设计目的：</li>
		 * </ul>
		 * <ul>
		 * <b>修订历史</b>
		 * <li>1、</li>
		 * </ul>
		 * 
		 * @param <K>
		 * @param joinIdentificationVariable
		 * @return
		 */
		public < K > NotFetchingJoinClause < K > innerJoin (
		                                                     K joinIdentificationVariable )
		{
			NotFetchingJoinClause < K > joinClause =
			                                         new NotFetchingJoinClause < K > (
			                                                                           joinIdentificationVariable ,
			                                                                           FromClause.JoinType.INNER ) ;
			FromClause.this.joins
			                     .add ( joinClause ) ;
			return joinClause ;
		}

		/**
		 * <ul>
		 * <li>设计作者：刘川</li>
		 * <li>设计日期：2009-8-10</li>
		 * <li>设计时间：下午04:38:30</li>
		 * <li>设计目的：</li>
		 * </ul>
		 * <ul>
		 * <b>修订历史</b>
		 * <li>1、</li>
		 * </ul>
		 * 
		 * @param <K>
		 * @param joinIdentificationVariable
		 * @return
		 */
		public < K > JoinClause < K > innerJoinFetch (
		                                               Collection < K > joinIdentificationVariable )
		{
			JoinClause < K > joinClause =
			                              new JoinClause < K > (
			                                                     null ,
			                                                     FromClause.JoinType.INNER ,
			                                                     true ) ;
			FromClause.this.joins
			                     .add ( joinClause ) ;
			return joinClause ;
		}

		/**
		 * <ul>
		 * <li>设计作者：刘川</li>
		 * <li>设计日期：2009-8-10</li>
		 * <li>设计时间：下午04:38:25</li>
		 * <li>设计目的：</li>
		 * </ul>
		 * <ul>
		 * <b>修订历史</b>
		 * <li>1、</li>
		 * </ul>
		 * 
		 * @param <K>
		 * @param joinIdentificationVariable
		 * @return
		 */
		public < K > JoinClause < K > innerJoinFetch (
		                                               K joinIdentificationVariable )
		{
			JoinClause < K > joinClause =
			                              new JoinClause < K > (
			                                                     joinIdentificationVariable ,
			                                                     FromClause.JoinType.INNER ,
			                                                     true ) ;
			FromClause.this.joins
			                     .add ( joinClause ) ;
			return joinClause ;
		}

		/**
		 * <ul>
		 * <li>设计作者：刘川</li>
		 * <li>设计日期：2009-8-10</li>
		 * <li>设计时间：下午04:47:09</li>
		 * <li>设计目的：</li>
		 * </ul>
		 * <ul>
		 * <b>修订历史</b>
		 * <li>1、</li>
		 * </ul>
		 * 
		 * @param <K>
		 * @param joinIdentificationVariable
		 * @return
		 */
		public < K > NotFetchingJoinClause < K > leftOuterJoin (
		                                                         Collection < K > joinIdentificationVariable )
		{
			NotFetchingJoinClause < K > joinClause =
			                                         new NotFetchingJoinClause < K > (
			                                                                           null ,
			                                                                           FromClause.JoinType.LEFT ) ;
			FromClause.this.joins
			                     .add ( joinClause ) ;
			return joinClause ;
		}

		/**
		 * <ul>
		 * <li>设计作者：刘川</li>
		 * <li>设计日期：2009-8-10</li>
		 * <li>设计时间：下午04:47:04</li>
		 * <li>设计目的：</li>
		 * </ul>
		 * <ul>
		 * <b>修订历史</b>
		 * <li>1、</li>
		 * </ul>
		 * 
		 * @param <K>
		 * @param joinIdentificationVariable
		 * @return
		 */
		public < K > NotFetchingJoinClause < K > leftOuterJoin (
		                                                         K joinIdentificationVariable )
		{
			NotFetchingJoinClause < K > joinClause =
			                                         new NotFetchingJoinClause < K > (
			                                                                           joinIdentificationVariable ,
			                                                                           FromClause.JoinType.LEFT ) ;
			FromClause.this.joins
			                     .add ( joinClause ) ;
			return joinClause ;
		}

		/**
		 * <ul>
		 * <li>设计作者：刘川</li>
		 * <li>设计日期：2009-8-10</li>
		 * <li>设计时间：下午04:47:00</li>
		 * <li>设计目的：</li>
		 * </ul>
		 * <ul>
		 * <b>修订历史</b>
		 * <li>1、</li>
		 * </ul>
		 * 
		 * @param <K>
		 * @param joinIdentificationVariable
		 * @return
		 */
		public < K > JoinClause < K > leftOuterJoinFetch (
		                                                   Collection < K > joinIdentificationVariable )
		{
			JoinClause < K > joinClause =
			                              new JoinClause < K > (
			                                                     null ,
			                                                     FromClause.JoinType.LEFT ,
			                                                     true ) ;
			FromClause.this.joins
			                     .add ( joinClause ) ;
			return joinClause ;
		}

		/**
		 * <ul>
		 * <li>设计作者：刘川</li>
		 * <li>设计日期：2009-8-10</li>
		 * <li>设计时间：下午04:46:55</li>
		 * <li>设计目的：</li>
		 * </ul>
		 * <ul>
		 * <b>修订历史</b>
		 * <li>1、</li>
		 * </ul>
		 * 
		 * @param <K>
		 * @param joinIdentificationVariable
		 * @return
		 */
		public < K > JoinClause < K > leftOuterJoinFetch (
		                                                   K joinIdentificationVariable )
		{
			JoinClause < K > joinClause =
			                              new JoinClause < K > (
			                                                     joinIdentificationVariable ,
			                                                     FromClause.JoinType.LEFT ,
			                                                     true ) ;
			FromClause.this.joins
			                     .add ( joinClause ) ;
			return joinClause ;
		}

		/**
		 * <ul>
		 * <li>设计作者：刘川</li>
		 * <li>设计日期：2009-8-10</li>
		 * <li>设计时间：下午04:46:46</li>
		 * <li>设计目的：</li>
		 * </ul>
		 * <ul>
		 * <b>修订历史</b>
		 * <li>1、</li>
		 * </ul>
		 * 
		 * @param character
		 * @return
		 */
		public OrderByClause orderBy (
		                               Character character )
		{
			return this
			           .orderBy (
			                      character ,
			                      SortDirection.ASC ) ;
		}

		/**
		 * <ul>
		 * <li>设计作者：刘川</li>
		 * <li>设计日期：2009-8-10</li>
		 * <li>设计时间：下午04:46:36</li>
		 * <li>设计目的：</li>
		 * </ul>
		 * <ul>
		 * <b>修订历史</b>
		 * <li>1、</li>
		 * </ul>
		 * 
		 * @param character
		 * @param sortDirection
		 * @return
		 */
		public OrderByClause orderBy (
		                               Character character ,
		                               SortDirection sortDirection )
		{
			return new OrderByClause (
			                           FromClause.this ,
			                           character ,
			                           sortDirection ) ;
		}

		/**
		 * <ul>
		 * <li>设计作者：刘川</li>
		 * <li>设计日期：2009-8-10</li>
		 * <li>设计时间：下午04:46:40</li>
		 * <li>设计目的：</li>
		 * </ul>
		 * <ul>
		 * <b>修订历史</b>
		 * <li>1、</li>
		 * </ul>
		 * 
		 * @param date
		 * @return
		 */
		public OrderByClause orderBy (
		                               Date date )
		{
			return this
			           .orderBy (
			                      date ,
			                      SortDirection.ASC ) ;
		}

		/**
		 * <ul>
		 * <li>设计作者：刘川</li>
		 * <li>设计日期：2009-8-10</li>
		 * <li>设计时间：下午04:45:57</li>
		 * <li>设计目的：</li>
		 * </ul>
		 * <ul>
		 * <b>修订历史</b>
		 * <li>1、</li>
		 * </ul>
		 * 
		 * @param date
		 * @param sortDirection
		 * @return
		 */
		public OrderByClause orderBy (
		                               Date date ,
		                               SortDirection sortDirection )
		{
			return new OrderByClause (
			                           FromClause.this ,
			                           date ,
			                           sortDirection ) ;
		}

		/**
		 * <ul>
		 * <li>设计作者：刘川</li>
		 * <li>设计日期：2009-8-10</li>
		 * <li>设计时间：下午04:45:42</li>
		 * <li>设计目的：</li>
		 * </ul>
		 * <ul>
		 * <b>修订历史</b>
		 * <li>1、</li>
		 * </ul>
		 * 
		 * @param number
		 * @return
		 */
		public OrderByClause orderBy (
		                               Number number )
		{
			return this
			           .orderBy (
			                      number ,
			                      SortDirection.ASC ) ;
		}

		/**
		 * <ul>
		 * <li>设计作者：刘川</li>
		 * <li>设计日期：2009-8-10</li>
		 * <li>设计时间：下午04:45:32</li>
		 * <li>设计目的：</li>
		 * </ul>
		 * <ul>
		 * <b>修订历史</b>
		 * <li>1、</li>
		 * </ul>
		 * 
		 * @param number
		 * @param sortDirection
		 * @return
		 */
		public OrderByClause orderBy (
		                               Number number ,
		                               SortDirection sortDirection )
		{
			return new OrderByClause (
			                           FromClause.this ,
			                           number ,
			                           sortDirection ) ;
		}

		/**
		 * <ul>
		 * <li>设计作者：刘川</li>
		 * <li>设计日期：2009-8-10</li>
		 * <li>设计时间：下午04:45:04</li>
		 * <li>设计目的：</li>
		 * </ul>
		 * <ul>
		 * <b>修订历史</b>
		 * <li>1、</li>
		 * </ul>
		 * 
		 * @param string
		 * @return
		 */
		public OrderByClause orderBy (
		                               String string )
		{
			return this
			           .orderBy (
			                      string ,
			                      SortDirection.ASC ) ;
		}

		/**
		 * <ul>
		 * <li>设计作者：刘川</li>
		 * <li>设计日期：2009-8-10</li>
		 * <li>设计时间：下午04:45:01</li>
		 * <li>设计目的：</li>
		 * </ul>
		 * <ul>
		 * <b>修订历史</b>
		 * <li>1、</li>
		 * </ul>
		 * 
		 * @param string
		 * @param sortDirection
		 * @return
		 */
		public OrderByClause orderBy (
		                               String string ,
		                               SortDirection sortDirection )
		{
			return new OrderByClause (
			                           FromClause.this ,
			                           string ,
			                           sortDirection ) ;
		}

		/**
		 * @see java.lang.Object#toString()
		 */
		@ Override
		public String toString ( )
		{
			return FromClause.this
			                      .toString ( ) ;
		}

		/**
		 * <ul>
		 * <li>设计作者：刘川</li>
		 * <li>设计日期：2009-8-10</li>
		 * <li>设计时间：下午04:44:29</li>
		 * <li>设计目的：</li>
		 * </ul>
		 * <ul>
		 * <b>修订历史</b>
		 * <li>1、</li>
		 * </ul>
		 * 
		 * @param conditionalExpression
		 * @return
		 */
		public WhereClause < S > where (
		                                 ConditionalExpression conditionalExpression )
		{
			return new WhereClause < S > (
			                               FromClause.this ,
			                               conditionalExpression ) ;
		}

	}

	/**
	 * <ul>
	 * <li>设计作者：刘川</li>
	 * <li>设计日期：2009-8-10</li>
	 * <li>设计时间：下午04:44:25</li>
	 * <li>设计目的：</li>
	 * </ul>
	 * <ul>
	 * <b>修订历史</b>
	 * <li>1、</li>
	 * </ul>
	 * 
	 * @param <J>
	 */
	public class NotFetchingJoinClause < J > extends JoinClause < J >
	{
		private NotFetchingJoinClause (
		                                J joinIdentificationVariable ,
		                                JoinType joinType )
		{
			super (
			        joinIdentificationVariable ,
			        joinType ,
			        false ) ;
		}

		/**
		 * <ul>
		 * <li>设计作者：刘川</li>
		 * <li>设计日期：2009-8-10</li>
		 * <li>设计时间：下午04:44:22</li>
		 * <li>设计目的：</li>
		 * </ul>
		 * <ul>
		 * <b>修订历史</b>
		 * <li>1、</li>
		 * </ul>
		 * 
		 * @param alias
		 * @return
		 */
		public FromClause < T , S > as (
		                                 J alias )
		{
			this.joinIdentificationVariable =
			                                  alias ;
			return FromClause.this ;
		}

	}

	private T	                           identificationVariable ;

	private final List < JoinClause < ? >>	joins	=
	                                                  new ArrayList < JoinClause < ? >> ( ) ;

	/**
	 * 构造函数
	 * 
	 * @param previousClauseFragment
	 */
	protected FromClause (
	                       AbstractClause previousClauseFragment )
	{
		super (
		        previousClauseFragment ) ;
	}

	/**
	 * 构造函数
	 * 
	 * @param previousClause
	 * @param identificationVariable
	 */
	public FromClause (
	                    AbstractClause previousClause ,
	                    T identificationVariable )
	{
		super (
		        previousClause ) ;
		this.identificationVariable =
		                              identificationVariable ;
	}

	/**
	 * <ul>
	 * <li>设计作者：刘川</li>
	 * <li>设计日期：2009-8-10</li>
	 * <li>设计时间：下午04:44:11</li>
	 * <li>设计目的：</li>
	 * </ul>
	 * <ul>
	 * <b>修订历史</b>
	 * <li>1、</li>
	 * </ul>
	 * 
	 * @param <J>
	 * @param joinIdentificationVariable
	 * @return
	 */
	@ SuppressWarnings ( "unchecked" )
	private < J > J rememberUnaliasedCollection (
	                                              Collection < J > joinIdentificationVariable )
	{
		CollectionAssociationPath < J > about =
		                                        ( CollectionAssociationPath < J > ) AliasFactory
		                                                                                        .about ( joinIdentificationVariable ) ;
		J collElement =
		                about
		                     .getElementProxy ( ) ;
		String path =
		              about
		                   .getPreferredStringRepresentation ( ) ;
		AliasFactory
		            .rememberAsAssociationPath (
		                                         collElement ,
		                                         path ) ;
		return collElement ;
	}

	/**
	 * @see com.hy.enterprise.framework.persistence.domain.query.AbstractClause#addTo(java.lang.StringBuilder)
	 */
	@ Override
	StringBuilder addTo (
	                      StringBuilder stringBuilder )
	{
		if ( this.previousClause instanceof FromClause )
		{
			stringBuilder
			             .append ( ", " ) ;
		}
		else
		{
			stringBuilder
			             .append ( " FROM " ) ;
		}

		AliasedLibraManagedObject aliased =
		                                    ( AliasedLibraManagedObject ) AliasFactory
		                                                                              .about ( this.identificationVariable ) ;

		stringBuilder
		             .append (
		                       aliased
		                              .getTargetRepresentation ( ) )
		             .append (
		                       " AS " )
		             .append (
		                       aliased
		                              .getAlias ( ) ) ;

		for ( JoinClause < ? > jc : this.joins )
		{
			LibraManagedObject jAbout =
			                            AliasFactory
			                                        .about ( jc.joinIdentificationVariable ) ;
			String sFetch =
			                jc.fetch
			                        ? "FETCH "
			                        : "" ;
			stringBuilder
			             .append (
			                       jc.joinType.stringForm )
			             .append (
			                       sFetch )
			             .append (
			                       jAbout
			                             .getTargetRepresentation ( ) ) ;

			if ( ! jc.fetch )
			{
				AliasedLibraManagedObject jAliased =
				                                     ( AliasedLibraManagedObject ) jAbout ;
				stringBuilder
				             .append (
				                       " AS " )
				             .append (
				                       jAliased
				                               .getAlias ( ) ) ;
			}
		}

		return stringBuilder ;
	}

	/**
	 * <ul>
	 * <li>设计作者：刘川</li>
	 * <li>设计日期：2009-8-10</li>
	 * <li>设计时间：下午04:43:26</li>
	 * <li>设计目的：</li>
	 * </ul>
	 * <ul>
	 * <b>修订历史</b>
	 * <li>1、</li>
	 * </ul>
	 * 
	 * @param <U>
	 * @param type
	 * @return
	 */
	public < U > FromClause < U , S > andFrom (
	                                            Class < U > type )
	{
		return new AbstractSchemaTypeFromClause < U , S > (
		                                                    this ,
		                                                    type ) ;
	}

	/**
	 * <ul>
	 * <li>设计作者：刘川</li>
	 * <li>设计日期：2009-8-10</li>
	 * <li>设计时间：下午04:43:23</li>
	 * <li>设计目的：</li>
	 * </ul>
	 * <ul>
	 * <b>修订历史</b>
	 * <li>1、</li>
	 * </ul>
	 * 
	 * @param <U>
	 * @param invalid
	 */
	public < U > void andFrom (
	                            Collection < U > invalid )
	{
	}

	/**
	 * <ul>
	 * <li>设计作者：刘川</li>
	 * <li>设计日期：2009-8-10</li>
	 * <li>设计时间：下午04:43:19</li>
	 * <li>设计目的：</li>
	 * </ul>
	 * <ul>
	 * <b>修订历史</b>
	 * <li>1、</li>
	 * </ul>
	 * 
	 * @param <U>
	 * @param inCollection
	 * @return
	 */
	public < U > FromClause < U , S > andFrom (
	                                            InCollection < U > inCollection )
	{
		return new InCollectionFromClause < U , S > (
		                                              this ,
		                                              inCollection ) ;
	}

	/**
	 * <ul>
	 * <li>设计作者：刘川</li>
	 * <li>设计日期：2009-8-10</li>
	 * <li>设计时间：下午04:43:15</li>
	 * <li>设计目的：</li>
	 * </ul>
	 * <ul>
	 * <b>修订历史</b>
	 * <li>1、</li>
	 * </ul>
	 * 
	 * @param <U>
	 * @param invalid
	 */
	public < U > void andFrom (
	                            U invalid )
	{
	}

	/**
	 * <ul>
	 * <li>设计作者：刘川</li>
	 * <li>设计日期：2009-8-10</li>
	 * <li>设计时间：下午04:43:11</li>
	 * <li>设计目的：</li>
	 * </ul>
	 * <ul>
	 * <b>修订历史</b>
	 * <li>1、</li>
	 * </ul>
	 * 
	 * @param alias
	 * @return
	 */
	public FromClause < T , S > as (
	                                 T alias )
	{
		this.identificationVariable =
		                              alias ;
		return this ;
	}

	/**
	 * <ul>
	 * <li>设计作者：刘川</li>
	 * <li>设计日期：2009-8-10</li>
	 * <li>设计时间：下午04:43:03</li>
	 * <li>设计目的：</li>
	 * </ul>
	 * <ul>
	 * <b>修订历史</b>
	 * <li>1、</li>
	 * </ul>
	 * 
	 * @param groupByItem
	 * @param more
	 * @return
	 */
	public GroupByClause < S > groupBy (
	                                     Object groupByItem ,
	                                     Object ... more )
	{
		return new GroupByClause < S > (
		                                 this ,
		                                 ObjectUtil
		                                           .merge (
		                                                    Object.class ,
		                                                    groupByItem ,
		                                                    more ) ) ;
	}

	/**
	 * <ul>
	 * <li>设计作者：刘川</li>
	 * <li>设计日期：2009-8-10</li>
	 * <li>设计时间：下午04:42:56</li>
	 * <li>设计目的：</li>
	 * </ul>
	 * <ul>
	 * <b>修订历史</b>
	 * <li>1、</li>
	 * </ul>
	 * 
	 * @param <J>
	 * @param joinIdentificationVariable
	 * @return
	 */
	public < J > NotFetchingJoinClause < J > innerJoin (
	                                                     Collection < J > joinIdentificationVariable )
	{
		NotFetchingJoinClause < J > joinClause =
		                                         new NotFetchingJoinClause < J > (
		                                                                           null ,
		                                                                           FromClause.JoinType.INNER ) ;
		this.joins
		          .add ( joinClause ) ;
		return joinClause ;
	}

	/**
	 * <ul>
	 * <li>设计作者：刘川</li>
	 * <li>设计日期：2009-8-10</li>
	 * <li>设计时间：下午04:42:53</li>
	 * <li>设计目的：</li>
	 * </ul>
	 * <ul>
	 * <b>修订历史</b>
	 * <li>1、</li>
	 * </ul>
	 * 
	 * @param <J>
	 * @param joinIdentificationVariable
	 * @return
	 */
	public < J > NotFetchingJoinClause < J > innerJoin (
	                                                     J joinIdentificationVariable )
	{
		NotFetchingJoinClause < J > joinClause =
		                                         new NotFetchingJoinClause < J > (
		                                                                           joinIdentificationVariable ,
		                                                                           FromClause.JoinType.INNER ) ;
		this.joins
		          .add ( joinClause ) ;
		return joinClause ;
	}

	/**
	 * <ul>
	 * <li>设计作者：刘川</li>
	 * <li>设计日期：2009-8-10</li>
	 * <li>设计时间：下午04:42:48</li>
	 * <li>设计目的：</li>
	 * </ul>
	 * <ul>
	 * <b>修订历史</b>
	 * <li>1、</li>
	 * </ul>
	 * 
	 * @param <J>
	 * @param joinIdentificationVariable
	 * @return
	 */
	public < J > JoinClause < J > innerJoinFetch (
	                                               Collection < J > joinIdentificationVariable )
	{
		J collElement =
		                this
		                    .rememberUnaliasedCollection ( joinIdentificationVariable ) ;

		JoinClause < J > joinClause =
		                              this.new JoinClause < J > (
		                                                          collElement ,
		                                                          FromClause.JoinType.INNER ,
		                                                          true ) ;
		this.joins
		          .add ( joinClause ) ;
		return joinClause ;
	} ;

	/**
	 * <ul>
	 * <li>设计作者：刘川</li>
	 * <li>设计日期：2009-8-10</li>
	 * <li>设计时间：下午04:42:44</li>
	 * <li>设计目的：</li>
	 * </ul>
	 * <ul>
	 * <b>修订历史</b>
	 * <li>1、</li>
	 * </ul>
	 * 
	 * @param <J>
	 * @param joinIdentificationVariable
	 * @return
	 */
	public < J > JoinClause < J > innerJoinFetch (
	                                               J joinIdentificationVariable )
	{
		JoinClause < J > joinClause =
		                              this.new JoinClause < J > (
		                                                          joinIdentificationVariable ,
		                                                          FromClause.JoinType.INNER ,
		                                                          true ) ;
		this.joins
		          .add ( joinClause ) ;
		return joinClause ;
	} ;

	/**
	 * <ul>
	 * <li>设计作者：刘川</li>
	 * <li>设计日期：2009-8-10</li>
	 * <li>设计时间：下午04:42:39</li>
	 * <li>设计目的：</li>
	 * </ul>
	 * <ul>
	 * <b>修订历史</b>
	 * <li>1、</li>
	 * </ul>
	 * 
	 * @param <J>
	 * @param joinIdentificationVariable
	 * @return
	 */
	public < J > NotFetchingJoinClause < J > leftOuterJoin (
	                                                         Collection < J > joinIdentificationVariable )
	{
		NotFetchingJoinClause < J > joinClause =
		                                         new NotFetchingJoinClause < J > (
		                                                                           null ,
		                                                                           FromClause.JoinType.LEFT ) ;
		this.joins
		          .add ( joinClause ) ;
		return joinClause ;
	}

	/**
	 * <ul>
	 * <li>设计作者：刘川</li>
	 * <li>设计日期：2009-8-10</li>
	 * <li>设计时间：下午04:42:35</li>
	 * <li>设计目的：</li>
	 * </ul>
	 * <ul>
	 * <b>修订历史</b>
	 * <li>1、</li>
	 * </ul>
	 * 
	 * @param <J>
	 * @param joinIdentificationVariable
	 * @return
	 */
	public < J > NotFetchingJoinClause < J > leftOuterJoin (
	                                                         J joinIdentificationVariable )
	{
		NotFetchingJoinClause < J > joinClause =
		                                         new NotFetchingJoinClause < J > (
		                                                                           joinIdentificationVariable ,
		                                                                           FromClause.JoinType.LEFT ) ;
		this.joins
		          .add ( joinClause ) ;
		return joinClause ;
	}

	/**
	 * <ul>
	 * <li>设计作者：刘川</li>
	 * <li>设计日期：2009-8-10</li>
	 * <li>设计时间：下午04:42:31</li>
	 * <li>设计目的：</li>
	 * </ul>
	 * <ul>
	 * <b>修订历史</b>
	 * <li>1、</li>
	 * </ul>
	 * 
	 * @param <J>
	 * @param joinIdentificationVariable
	 * @return
	 */
	public < J > JoinClause < J > leftOuterJoinFetch (
	                                                   Collection < J > joinIdentificationVariable )
	{
		J collElement =
		                this
		                    .rememberUnaliasedCollection ( joinIdentificationVariable ) ;

		JoinClause < J > joinClause =
		                              new JoinClause < J > (
		                                                     collElement ,
		                                                     FromClause.JoinType.LEFT ,
		                                                     true ) ;
		this.joins
		          .add ( joinClause ) ;
		return joinClause ;
	}

	/**
	 * <ul>
	 * <li>设计作者：刘川</li>
	 * <li>设计日期：2009-8-10</li>
	 * <li>设计时间：下午04:42:26</li>
	 * <li>设计目的：</li>
	 * </ul>
	 * <ul>
	 * <b>修订历史</b>
	 * <li>1、</li>
	 * </ul>
	 * 
	 * @param <J>
	 * @param joinIdentificationVariable
	 * @return
	 */
	public < J > JoinClause < J > leftOuterJoinFetch (
	                                                   J joinIdentificationVariable )
	{
		JoinClause < J > joinClause =
		                              new JoinClause < J > (
		                                                     joinIdentificationVariable ,
		                                                     FromClause.JoinType.LEFT ,
		                                                     true ) ;
		this.joins
		          .add ( joinClause ) ;
		return joinClause ;
	}

	/**
	 * <ul>
	 * <li>设计作者：刘川</li>
	 * <li>设计日期：2009-8-10</li>
	 * <li>设计时间：下午04:42:20</li>
	 * <li>设计目的：</li>
	 * </ul>
	 * <ul>
	 * <b>修订历史</b>
	 * <li>1、</li>
	 * </ul>
	 * 
	 * @param object
	 * @return
	 */
	public OrderByClause orderBy (
	                               Object object )
	{
		return this
		           .orderBy (
		                      object ,
		                      SortDirection.ASC ) ;
	}

	/**
	 * <ul>
	 * <li>设计作者：刘川</li>
	 * <li>设计日期：2009-8-10</li>
	 * <li>设计时间：下午04:42:05</li>
	 * <li>设计目的：</li>
	 * </ul>
	 * <ul>
	 * <b>修订历史</b>
	 * <li>1、</li>
	 * </ul>
	 * 
	 * @param object
	 * @param sortDirection
	 * @return
	 */
	public OrderByClause orderBy (
	                               Object object ,
	                               SortDirection sortDirection )
	{
		return new OrderByClause (
		                           this ,
		                           object ,
		                           sortDirection ) ;
	}

	/**
	 * <ul>
	 * <li>设计作者：刘川</li>
	 * <li>设计日期：2009-8-10</li>
	 * <li>设计时间：下午04:41:23</li>
	 * <li>设计目的：</li>
	 * </ul>
	 * <ul>
	 * <b>修订历史</b>
	 * <li>1、</li>
	 * </ul>
	 * 
	 * @param condition
	 * @return
	 */
	public WhereClause < S > where (
	                                 ConditionalExpression condition )
	{
		return new WhereClause < S > (
		                               this ,
		                               condition ) ;
	}
}